#include "gtest/gtest.h"
#include "../BaseUtil/MyTest.h"
#include "DOMEventImp.h"
namespace DOMEventImp {

class MouseEventImpTest : public testing::Test {
protected:
	class DummyEventTarget : IMPLEMENTS( EventTarget ) {
	public:
		virtual void addEventListener(DOMString type, EventListener * listener, bool useCapture) {}
		virtual void removeEventListener(DOMString type, EventListener * listener, bool useCapture) {}
		virtual bool dispatchEvent(Event * evt) throw(EventExceptionPtr) { return false; }
	};

	virtual void SetUp() {}
    virtual void TearDown() {}
};

TEST_F(MouseEventImpTest, Observer1) {
	int coordinates[] = { 0, 10, 20, 30, 100 };
	bool true_false[] = { true, false };
	unsigned int mouseButton[] = { MouseEvent::LEFT_MOUSE_BUTTON,
			MouseEvent::MIDDLE_MOUSE_BUTTON, MouseEvent::RIGHT_MOUSE_BUTTON };
	EventTarget * relatedTarget[] = { new DummyEventTarget(), NULL };

	typedef LOKI_TYPELIST_10(int, int, int, int /*4th*/, bool, bool, bool, bool /*8th*/,
			unsigned int, EventTarget *) MouseEventTestType;
	HeteroVector< MouseEventTestType > inputs;
	enum { ScreenX, ScreenY, ClientX, ClientY, CtrlKey, AltKey, ShiftKey, MetaKey, MouseButton, RelatedTarget };
	inputs.set< ScreenX >( coordinates );
	inputs.set< ScreenY >( coordinates );
	inputs.set< ClientX >( coordinates );
	inputs.set< ClientY >( coordinates );
	inputs.set< CtrlKey >( true_false );
	inputs.set< AltKey >( true_false );
	inputs.set< ShiftKey >( true_false );
	inputs.set< MetaKey >( true_false );
	inputs.set< MouseButton >( mouseButton );
	inputs.set< RelatedTarget >( relatedTarget );

	HeteroVector< MouseEventTestType > BCC = allCombinationsCoverage( inputs );

	const unsigned int sizeOfBCC = BCC.size< 0 >();
	for(unsigned int idx = 0; idx < sizeOfBCC; ++idx )
	{
		MouseEvent * evt = new MouseEventImp(NULL, NULL, "", true, true, NULL, 5,
				BCC.get< ScreenX >(idx), BCC.get< ScreenY >(idx),
				BCC.get< ClientX >(idx), BCC.get< ClientY >(idx),
				BCC.get< CtrlKey >(idx), BCC.get< AltKey >(idx),
				BCC.get< ShiftKey >(idx), BCC.get< MetaKey >(idx),
				BCC.get< MouseButton >(idx), BCC.get< RelatedTarget >(idx) );

		ASSERT_EQ(BCC.get< ScreenX >(idx), evt->getScreenX()) << idx;
		ASSERT_EQ(BCC.get< ScreenY >(idx), evt->getScreenY()) << idx;
		ASSERT_EQ(BCC.get< ClientX >(idx), evt->getClientX()) << idx;
		ASSERT_EQ(BCC.get< ClientY >(idx), evt->getClientY()) << idx;
		ASSERT_EQ(BCC.get< CtrlKey >(idx), evt->getCtrlKey()) << idx;
		ASSERT_EQ(BCC.get< AltKey >(idx), evt->getAltKey()) << idx;
		ASSERT_EQ(BCC.get< ShiftKey >(idx), evt->getShiftKey()) << idx;
		ASSERT_EQ(BCC.get< MetaKey >(idx), evt->getMetaKey()) << idx;
		ASSERT_EQ(BCC.get< MouseButton >(idx), evt->getButton()) << idx;
		ASSERT_EQ(BCC.get< RelatedTarget >(idx), evt->getRelatedTarget()) << idx;
	}

	delete relatedTarget[0];
}

}

